package com.xmall.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmall.define.base.ResultCode;
import com.xmall.define.constants.CommonConstants;
import com.xmall.exception.XmallException;
import com.xmall.product.define.dto.group.GroupDo;
import com.xmall.product.define.dto.group.GroupDto;
import com.xmall.product.define.request.group.GroupQueryParams;
import com.xmall.product.define.request.group.GroupUpdateRequest;
import com.xmall.product.entity.BaseAttr;
import com.xmall.product.entity.Group;
import com.xmall.product.mapper.GroupMapper;
import com.xmall.product.service.IAttrOptionService;
import com.xmall.product.service.IBaseAttrService;
import com.xmall.product.service.IGroupService;
import com.xmall.product.utils.ConvertUtils;
import com.xmall.utils.XmallUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 属性分组 服务实现类
 * </p>
 *
 * @author xmall
 * @since 2023-11-02
 */
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements IGroupService {

    @Resource
    private IBaseAttrService attrService;

    @Resource
    private IAttrOptionService attrOptionService;

    @Override
    public void saveEntity(GroupUpdateRequest request) {
        // 校验重复性（相同分类下的名称不能重复）
        List<Group> list = this.list(new QueryWrapper<Group>()
                .eq("category_id", request.getCategoryId())
                .eq("name", request.getName()));
        if(CollectionUtil.isNotEmpty(list)){
            throw new XmallException(ResultCode.PRODUCT_GROUP_NAME_REPEAT);
        }

        // 获取排序值
        Integer maxSort = this.baseMapper.getMaxSort(request.getCategoryId());
        request.setSort(null == maxSort ? CommonConstants.DEFAULT_SORT_NUM : maxSort + 1);

        this.save(ConvertUtils.GroupModule.INSTANCE.toEntity(request));
    }

    @Override
    public void updateEntity(GroupUpdateRequest request) {
        Group entity = this.getById(request.getId());
        XmallUtils.notNull(entity);

        // 校验重复性（相同分类下的名称不能重复）
        List<Group> list = this.list(new QueryWrapper<Group>()
                .eq("category_id", request.getCategoryId())
                .eq("name", request.getName()).ne("id", request.getId()));
        if(CollectionUtil.isNotEmpty(list)){
            throw new XmallException(ResultCode.PRODUCT_GROUP_NAME_REPEAT);
        }

        this.updateById(ConvertUtils.GroupModule.INSTANCE.toEntity(request));
    }

    /**
     * 删除
     */
    @Transactional
    @Override
    public void deleteEntity(Long id) {
        this.removeById(id);
        attrService.remove(new QueryWrapper<BaseAttr>().eq("group_id", id));
        attrOptionService.removeByGroupId(id);
    }

    /**
     * 交换排序值
     */
    @Transactional
    @Override
    public void swapSort(Long prevGroupId, Long nextGroupId) {
        Group prevGroup = this.getById(prevGroupId);
        Group nextGroup = this.getById(nextGroupId);

        XmallUtils.notNull(prevGroup);
        XmallUtils.notNull(nextGroup);

        Group updatePrevGroup = new Group();
        updatePrevGroup.setId(prevGroupId);
        updatePrevGroup.setSort(nextGroup.getSort());
        this.updateById(updatePrevGroup);

        Group updateNextGroup = new Group();
        updateNextGroup.setId(nextGroupId);
        updateNextGroup.setSort(prevGroup.getSort());
        this.updateById(updateNextGroup);
    }

    /**
     * 根据分类ID查询分组列表（普通属性）
     */
    @Override
    public List<GroupDto> listWithCascade(GroupQueryParams params) {
        List<GroupDo> list = this.baseMapper.listWithCascade(params);
        return ConvertUtils.GroupModule.INSTANCE.doList2DtoList(list).stream()
            .filter(groupAttrDto -> groupAttrDto.getAttrs().size() > 0).collect(Collectors.toList());
    }

    /**
     * 列表
     */
    @Override
    public List<GroupDto> list(GroupQueryParams request) {
        QueryWrapper<Group> query = new QueryWrapper<>();
        query.eq(null != request.getCategoryId(), "category_id", request.getCategoryId());
        query.orderByAsc("sort");

        return ConvertUtils.GroupModule.INSTANCE.toDtoList(this.list(query));
    }

    @Override
    public GroupDto info(Long id) {
        Group entity = this.getById(id);
        XmallUtils.notNull(entity);
        return ConvertUtils.GroupModule.INSTANCE.toDto(entity);
    }

}
